// +----------------------------------------------------------------------
// | JavaWeb_EleVue_Pro前后端分离旗舰版框架 [ JavaWeb ]
// +----------------------------------------------------------------------
// | 版权所有 2021 上海JavaWeb研发中心
// +----------------------------------------------------------------------
// | 官方网站: http://www.javaweb.vip/
// +----------------------------------------------------------------------
// | 作者: 鲲鹏 <javaweb520@gmail.com>
// +----------------------------------------------------------------------
// | 免责声明:
// | 本软件框架禁止任何单位和个人用于任何违法、侵害他人合法利益等恶意的行为，禁止用于任何违
// | 反我国法律法规的一切平台研发，任何单位和个人使用本软件框架用于产品研发而产生的任何意外
// | 、疏忽、合约毁坏、诽谤、版权或知识产权侵犯及其造成的损失 (包括但不限于直接、间接、附带
// | 或衍生的损失等)，本团队不承担任何法律责任。本软件框架只能用于公司和个人内部的法律所允
// | 许的合法合规的软件产品研发，详细声明内容请阅读《框架免责声明》附件；
// +----------------------------------------------------------------------

package com.javaweb.admin.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.XmlUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.javaweb.admin.entity.KdlSaleOutQc;
import com.javaweb.admin.entity.NcServiceLog;
import com.javaweb.admin.mapper.KDLCustomerMapper;
import com.javaweb.admin.mapper.KdlSaleOutQcMapper;
import com.javaweb.admin.query.KdlCallBaseQuery;
import com.javaweb.admin.query.KdlSaleOutQcQuery;
import com.javaweb.admin.service.IKdlSaleOutQcService;
import com.javaweb.admin.service.INcServiceLogService;
import com.javaweb.admin.vo.kdlsaleoutqc.KdlSaleOutQcInfoVo;
import com.javaweb.admin.vo.kdlsaleoutqc.KdlSaleOutQcListVo;
import com.javaweb.common.common.BaseQuery;
import com.javaweb.common.common.BaseServiceImpl;
import com.javaweb.common.config.CommonConfig;
import com.javaweb.common.config.DataSourceType;
import com.javaweb.common.config.DynamicDataSource;
import com.javaweb.common.config.SpecifyDataSource;
import com.javaweb.common.utils.CommonUtils;
import com.javaweb.common.utils.DateUtils;
import com.javaweb.common.utils.JsonResult;
import com.javaweb.common.utils.StringUtils;
import com.javaweb.system.service.IDictDataService;
import com.javaweb.system.utils.ShiroUtils;
import com.seegw.shaphar.KDLRequest;
import com.sphsine.bip.SHYPConstants;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 销售出库质检 服务类实现
 * </p>
 *
 * @author 鲲鹏
 * @since 2024-02-21
 */
@Service
public class KdlSaleOutQcServiceImpl extends BaseServiceImpl<KdlSaleOutQcMapper, KdlSaleOutQc> implements IKdlSaleOutQcService {

    @Autowired
    private KdlSaleOutQcMapper kdlSaleOutQcMapper;


    @Autowired
    private INcServiceLogService ncServiceLogService;

    @Autowired
    private IDictDataService dictDataService;

    @Autowired
    private KDLCustomerMapper kdlCustomerMapper;
    /**
     * 获取数据列表
     *
     * @param query 查询条件
     * @return
     */
    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public JsonResult getList(BaseQuery query) {
        KdlSaleOutQcQuery kdlSaleOutQcQuery = (KdlSaleOutQcQuery) query;
        // 查询条件
        QueryWrapper<KdlSaleOutQc> queryWrapper = new QueryWrapper<>();
        if(!StringUtils.isEmpty(kdlSaleOutQcQuery.getVendorso())){
            queryWrapper.like("vendorso",kdlSaleOutQcQuery.getVendorso());
        }
        if(!StringUtils.isEmpty(kdlSaleOutQcQuery.getMaterialcode())){
            queryWrapper.like("materialcode",kdlSaleOutQcQuery.getMaterialcode());
        }
        if(!StringUtils.isEmpty(kdlSaleOutQcQuery.getRiqiBegin())){
            queryWrapper.gt("gidate",kdlSaleOutQcQuery.getRiqiBegin());
        }
        if(!StringUtils.isEmpty(kdlSaleOutQcQuery.getRiqiEnd())){
            queryWrapper.lt("gidate",kdlSaleOutQcQuery.getRiqiEnd());
        }
        if(!StringUtils.isEmpty(kdlSaleOutQcQuery.getRiqiEnd())){
            queryWrapper.lt("gidate",kdlSaleOutQcQuery.getRiqiEnd());
        }
        if(!StringUtils.isEmpty(kdlSaleOutQcQuery.getStatus())){
            queryWrapper.eq("status",kdlSaleOutQcQuery.getStatus());
        }


        queryWrapper.orderByDesc("gidate");
//        String switchCode = this.getDicStatus("SWITCH", "SWITCH_STORE", DataSourceType.SINESYS);
        //根据明细主键查库位
//        String chlocation = "1".equals(switchCode) ? kdlSaleOutQcMapper.getChlocation(vendordnlineno) : "1001";
        // 获取数据列表
        IPage<KdlSaleOutQc> page = new Page<>(kdlSaleOutQcQuery.getPage(), kdlSaleOutQcQuery.getLimit());
        IPage<KdlSaleOutQc> pageData = kdlSaleOutQcMapper.selectPage(page, queryWrapper);
        pageData.convert(x -> {
            KdlSaleOutQcListVo kdlSaleOutQcListVo = Convert.convert(KdlSaleOutQcListVo.class, x);
            kdlSaleOutQcListVo.setStatusName("Y".equals(kdlSaleOutQcListVo.getStatus()) ? "已回写" : "未回写");
            kdlSaleOutQcListVo.setNum((int)Float.parseFloat((kdlSaleOutQcListVo.getGiquantity())));
            kdlSaleOutQcListVo.setCustomernameVO(kdlCustomerMapper.getNameByCode(kdlSaleOutQcListVo.getCustomername()));
            return kdlSaleOutQcListVo;
        });
        return JsonResult.success(pageData);
    }

    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public JsonResult getSaleOutQCList(BaseQuery query) {
        KdlSaleOutQcQuery kdlSaleOutQcQuery = (KdlSaleOutQcQuery) query;
        kdlSaleOutQcQuery.setOrglist(ShiroUtils.getOrgCode());
        IPage<KdlSaleOutQcListVo> page = new Page<>(kdlSaleOutQcQuery.getPage(), kdlSaleOutQcQuery.getLimit());
        IPage<KdlSaleOutQcListVo> pageData = kdlSaleOutQcMapper.getSaleOutQCList(page, kdlSaleOutQcQuery);

        return JsonResult.success(pageData);
    }

    /**
     * 获取详情Vo
     *
     * @param id 记录ID
     * @return
     */
    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public Object getInfo(Serializable id) {
        KdlSaleOutQc entity = (KdlSaleOutQc) super.getInfo(id);
        // 返回视图Vo
        KdlSaleOutQcInfoVo kdlSaleOutQcInfoVo = new KdlSaleOutQcInfoVo();
        // 拷贝属性
        BeanUtils.copyProperties(entity, kdlSaleOutQcInfoVo);
        return kdlSaleOutQcInfoVo;
    }

    /**
     * 添加、更新记录
     *
     * @param entity 实体对象
     * @return
     */
    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public JsonResult edit(KdlSaleOutQc entity) {
        if (StringUtils.isNotNull(entity.getId()) && entity.getId() > 0) {
            entity.setUpdateUser(ShiroUtils.getUserId());
            entity.setUpdateTime(DateUtils.now());
        } else {
            entity.setCreateUser(ShiroUtils.getUserId());
            entity.setCreateTime(DateUtils.now());
        }
        return super.edit(entity);
    }

    /**
     * 删除记录
     *
     * @param entity 实体对象
     * @return
     */
    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public JsonResult delete(KdlSaleOutQc entity) {
        entity.setUpdateUser(1);
        entity.setUpdateTime(DateUtils.now());
        entity.setMark(0);
        return super.delete(entity);
    }

    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public JsonResult syncSaleOutQC(KdlCallBaseQuery query) {
        try {

            KDLRequest request = new KDLRequest(CommonConfig.kdlSandbox);
            //请求
            String responseBody = request.buildPostXmlData(query).postData(CommonConfig.kdlSandbox?SHYPConstants.KDL_GETCONFIRMATION_URL_SUFFIX_TEST:SHYPConstants.KDL_GETCONFIRMATION_URL_SUFFIX);
            Document docResult = XmlUtil.readXML(responseBody);

            ncServiceLogService.save(new NcServiceLog(request.getPostData(), responseBody,"9000", query.getPrincipalid() + "_" + query.getDoctype()));
            Element elementG = XmlUtil.getRootElement(docResult);
            List<KdlSaleOutQc> list = new ArrayList<>();
            for (int j = 0; j < elementG.getChildNodes().getLength(); j++) {
                Element elementGR = (Element) elementG.getChildNodes().item(j);
                Element headResult = XmlUtil.getElement(elementGR, "Head");
                Element detailResult = XmlUtil.getElement(elementGR, "Details");
                String resCode = CommonUtils.XmlGetNodeContent(headResult, "FunCode");
                String resRemark = CommonUtils.XmlGetNodeContent(headResult, "Remark");
                if (!"9000".equals(resCode)) {
                    //return null;
                    return JsonResult.error(resCode + ":" + resRemark);
                }
                for (int i = 0; i < detailResult.getChildNodes().getLength(); i++) {
                    Element detail = (Element) detailResult.getChildNodes().item(i);
                    KdlSaleOutQc qc = new KdlSaleOutQc();
                    list.add(qc);
                    qc.setPrincipalid(CommonUtils.XmlGetNodeContent(headResult, "PrincipalID"));
                    qc.setPrincipalname(CommonUtils.XmlGetNodeContent(headResult, "PrincipalName"));
                    qc.setVendorso(CommonUtils.XmlGetNodeContent(headResult, "VendorSO"));
                    qc.setDoctype(CommonUtils.XmlGetNodeContent(headResult, "DocType"));
                    qc.setCompanycode(CommonUtils.XmlGetNodeContent(headResult, "CompanyCode"));
                    qc.setGidate(CommonUtils.XmlGetNodeContent(headResult, "GIDate"));
                    qc.setCustomername(CommonUtils.XmlGetNodeContent(headResult, "CustomerName"));
                    qc.setShiptoaddress(CommonUtils.XmlGetNodeContent(headResult, "ShipToAddress"));
                    qc.setCahdnno(CommonUtils.XmlGetNodeContent(detail, "CAHDNNO"));
                    qc.setVendorsolineno(CommonUtils.XmlGetNodeContent(detail, "VendorSOLineNo"));
                    qc.setVendordnlineno(CommonUtils.XmlGetNodeContent(detail, "VendorDNLineNo"));
                    qc.setCandnlineno(CommonUtils.XmlGetNodeContent(detail, "CANDNlineNO"));
                    qc.setBoxflag(CommonUtils.XmlGetNodeContent(detail, "BoxFlag"));
                    qc.setBoxno(CommonUtils.XmlGetNodeContent(detail, "BoxNo"));
                    qc.setInspectionlot(CommonUtils.XmlGetNodeContent(detail, "InspectionLot"));
                    qc.setMaterialcode(CommonUtils.XmlGetNodeContent(detail, "MaterialCode"));
                    qc.setCahmaterialcode(CommonUtils.XmlGetNodeContent(detail, "CAHMaterialCode"));
                    qc.setMaterialdes(CommonUtils.XmlGetNodeContent(detail, "MaterialDes"));
                    qc.setComdescription(CommonUtils.XmlGetNodeContent(detail, "ComDescription"));
                    qc.setMaterialspec(CommonUtils.XmlGetNodeContent(detail, "MaterialSpec"));
                    qc.setMaterialform(CommonUtils.XmlGetNodeContent(detail, "MaterialForm"));
                    qc.setRegistno(CommonUtils.XmlGetNodeContent(detail, "RegistNo"));
                    qc.setProductgroupcode(CommonUtils.XmlGetNodeContent(detail, "ProductGroupCode"));
                    qc.setProductgroupdes(CommonUtils.XmlGetNodeContent(detail, "ProductGroupDes"));
                    qc.setGspcategorycode(CommonUtils.XmlGetNodeContent(detail, "GSPCategoryCode"));
                    qc.setGspcategorydes(CommonUtils.XmlGetNodeContent(detail, "GSPCategoryDes"));
                    qc.setGiquantity(CommonUtils.XmlGetNodeContent(detail, "GIQuantity"));
                    qc.setCahuom(CommonUtils.XmlGetNodeContent(detail, "CAHUOM"));
                    qc.setVendoruom(CommonUtils.XmlGetNodeContent(detail, "VendorUOM"));
                    qc.setGiplant(CommonUtils.XmlGetNodeContent(detail, "GIPlant"));
                    qc.setGiaddress(CommonUtils.XmlGetNodeContent(detail, "GIAddress"));
                    qc.setVendorplant(CommonUtils.XmlGetNodeContent(detail, "VendorPlant"));
                    qc.setVendorbatch(CommonUtils.XmlGetNodeContent(detail, "VendorBatch"));
                    qc.setSerialno(CommonUtils.XmlGetNodeContent(detail, "SerialNo"));
                    qc.setExpireddate(CommonUtils.XmlGetNodeContent(detail, "ExpiredDate"));
                    qc.setManufacturedate(CommonUtils.XmlGetNodeContent(detail, "ManufactureDate"));
                    qc.setManufacturername(CommonUtils.XmlGetNodeContent(detail, "ManufacturerName"));
                    qc.setQapassqty(CommonUtils.XmlGetNodeContent(detail, "QAPassQty"));
                    qc.setInspectionresult(CommonUtils.XmlGetNodeContent(detail, "InspectionResult"));
                    qc.setQarejectqty(CommonUtils.XmlGetNodeContent(detail, "QARejectQty"));
                    qc.setTreatmentforreject(CommonUtils.XmlGetNodeContent(detail, "TreatmentforReject"));
                    qc.setInspectionidname1(CommonUtils.XmlGetNodeContent(detail, "InspectionIDName1"));
                    qc.setInspectiondate1(CommonUtils.XmlGetNodeContent(detail, "InspectionDate1"));
                    qc.setInspectionidname2(CommonUtils.XmlGetNodeContent(detail, "InspectionIDName2"));
                    qc.setInspectiondate2(CommonUtils.XmlGetNodeContent(detail, "InspectionDate2"));
                    qc.setStoragecondition(CommonUtils.XmlGetNodeContent(detail, "StorageCondition"));
                    qc.setUdconclusion(CommonUtils.XmlGetNodeContent(detail, "UDConclusion"));
                    qc.setSyncTime(CommonUtils.XmlGetNodeContent(detail, "Time"));
                    qc.setStatus("N");
                    qc.setSapbatch(CommonUtils.XmlGetNodeContent(detail, "SAPbatch"));

                    try {
                        KdlSaleOutQc storeInfo = kdlSaleOutQcMapper.getStoreInfo(qc.getVendordnlineno());
                        qc.setStorcode(storeInfo.getStorcode());
                        qc.setStorname(storeInfo.getStorname());
                    } catch (Exception e) {

                    }

                    KdlSaleOutQc one = kdlSaleOutQcMapper.selectOne(new QueryWrapper<KdlSaleOutQc>().eq("vendorso", qc.getVendorso()).eq("cahdnno",qc.getCahdnno()).eq("VendorSOLineNo", qc.getVendorsolineno()));
                    if (one == null) {
                        kdlSaleOutQcMapper.insert(qc);
                    } else {
                        if(one.getStatus().equals("N")) {
                            qc.setUpdateTime(DateUtils.now());
                            qc.setId(one.getId());
                            kdlSaleOutQcMapper.updateById(qc);
                            //kdlSaleOutQcMapper.update(qc, new UpdateWrapper<KdlSaleOutQc>().eq("vendorso", qc.getVendorso()).eq("VendorSOLineNo", qc.getVendorsolineno()));
                        }
                    }
                }
            }
        } catch (Exception ex) {
            return JsonResult.error(ex.getMessage());
        }
        return JsonResult.success();
    }

    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public JsonResult updateCancelSaleOutQC(KdlCallBaseQuery query,String startTime, String endtime) {
        try {
            query.setStarttime(startTime);
            query.setEndtime(endtime);
            KDLRequest request = new KDLRequest(CommonConfig.kdlSandbox);
            //请求
            String responseBody = request.buildPostXmlData(query).postData(CommonConfig.kdlSandbox?SHYPConstants.KDL_GETCONFIRMATION_URL_SUFFIX_TEST:SHYPConstants.KDL_GETCONFIRMATION_URL_SUFFIX);
            Document docResult = XmlUtil.readXML(responseBody);
            ncServiceLogService.save(new NcServiceLog(request.getPostData(), responseBody,"9000", query.getPrincipalid() + "_" + query.getDoctype()));
            Element elementG = XmlUtil.getRootElement(docResult);
            List<KdlSaleOutQc> qcCancelList = new ArrayList<>();
            for (int j = 0; j < elementG.getChildNodes().getLength(); j++) {
                Element elementGR = (Element) elementG.getChildNodes().item(j);
                Element headResult = XmlUtil.getElement(elementGR, "Head");
                Element detailResult = XmlUtil.getElement(elementGR, "Details");
                String resCode = CommonUtils.XmlGetNodeContent(headResult, "FunCode");
                String resRemark = CommonUtils.XmlGetNodeContent(headResult, "Remark");
                if (!"9000".equals(resCode)) {
                    //return null;
                    return JsonResult.error(resCode + ":" + resRemark);
                }
                for (int i = 0; i < detailResult.getChildNodes().getLength(); i++) {
                    Element detail = (Element) detailResult.getChildNodes().item(i);
                    KdlSaleOutQc qc = new KdlSaleOutQc();
                    qc.setVendorso(CommonUtils.XmlGetNodeContent(headResult, "VendorSO"));
                    qc.setCahdnno(CommonUtils.XmlGetNodeContent(detail, "CAHDNNO"));
                    qc.setVendorsolineno(CommonUtils.XmlGetNodeContent(detail, "VendorSOLineNo"));
                    qc.setInspectionresult(CommonUtils.XmlGetNodeContent(detail, "InspectionResult"));
                    if ("取消".equals(qc.getInspectionresult())) {
                        qcCancelList.add(qc);
                        kdlSaleOutQcMapper.update(qc, new UpdateWrapper<KdlSaleOutQc>().eq("vendorso", qc.getVendorso()).eq("cahdnno",qc.getCahdnno()).eq("VendorSOLineNo", qc.getVendorsolineno()));
                    }
                }
            }
        } catch (Exception ex) {
            return JsonResult.error(ex.getMessage());
        }
        return JsonResult.success();
    }

    /**
     * 查询字段状态值
     *
     * @param dicCode
     * @param dicDataCode
     * @param dataSourceType
     * @return
     */
    private String getDicStatus(String dicCode, String dicDataCode, DataSourceType dataSourceType) {
        DynamicDataSource.setDataSource("system");
        String status = dictDataService.getDicStatus(dicCode, dicDataCode);
        DynamicDataSource.setDataSource(dataSourceType.getName());
        return status;
    }

    /**
     * 获取未回写NC的销售出库质检列表
     * @return
     */
    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public List<KdlSaleOutQc> getSaleOutSubmitList() {
        return kdlSaleOutQcMapper.getSaleOutSubmitList();
    }

    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public List<KdlSaleOutQcListVo> getSaleOutDetailList(String orderno) {
        return kdlSaleOutQcMapper.getSaleOutQcDetail(orderno);
    }


    /**
     * 获取康德乐销售出库最新同步时间
     * @return
     */
    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public String GetMaxSyncTime() {
        return kdlSaleOutQcMapper.GetMaxSyncTime();
    }
}
